#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

#include <vex/iterable/contract/range.h>
#include <vex/functional/result.h>
#include <vex/functional/replace_result.h>

namespace tests { namespace tests_functional_mc_replace_result {		

    namespace vf = vex::functional;
    namespace vi = vex::iterable;
    namespace mpl = boost::mpl;
    namespace bft = boost::function_types;

    TEST_CLASS(test_class)
    {
        BEGIN_TEST_CLASS_ATTRIBUTE()
            TEST_CLASS_ATTRIBUTE(L"Module", L"tests.functional.mc.replace_result")
        END_TEST_CLASS_ATTRIBUTE();
    public:
        TEST_METHOD(result_should_yield_the_result_type_of_a_function_signature)
        {
            Assert::IsTrue(std::is_same<void, 
                vf::result<void ()>::type
            >::value);
            Assert::IsTrue(std::is_same<std::string const &, 
                vf::result<std::string const & (int, double)>::type
            >::value);
            Assert::IsTrue(std::is_same<std::vector<int>, 
                vf::result<std::vector<int> (int, double, char)>::type
            >::value);
            Assert::IsTrue(std::is_same<std::vector<int>, 
                vf::result<std::vector<int> (int, double, char, std::string)>::type
            >::value);
            Assert::IsTrue(std::is_same<std::vector<int>, 
                vf::result<std::vector<int> (int, double, char, std::string, std::pair<int, double> const &)>::type
            >::value);
        }

        TEST_METHOD(replace_result_should_replace_the_result_type_of_a_function_signature_by_defined_type)
        {
            Assert::IsTrue(std::is_same<int (), 
                vf::replace_result<void (), int>::type
            >::value);

            Assert::IsTrue(std::is_same<
                std::vector<std::string> (int, double), 
                vf::replace_result< std::string const & (int, double), std::vector<std::string> >::type
            >::value);

            Assert::IsTrue(std::is_same<
                std::vector<std::string> (int, double, char), 
                vf::replace_result<std::vector<int> (int, double, char), std::vector<std::string> >::type
            >::value);

            Assert::IsTrue(std::is_same<
                vi::contract::range<vi::bidirectional, int>* const (int, double, char, std::string),
                vf::replace_result<int (int, double, char, std::string), vi::contract::range<vi::bidirectional, int>* const>::type
            >::value);

            Assert::IsTrue(std::is_same<
                std::string const & (int, double, char, std::string, std::pair<int, double> const &), 
                vf::replace_result<
                    int (int, double, char, std::string, std::pair<int, double> const &), std::string const &
                >::type
            >::value);
        }
    };
}}